//
//  ZSerializeDownloadPrivate.h
//  Part of Z-Way.C library
//
//  Created by Serguei Poltorak on 08.10.2024.
//
//  Copyright (c) 2024 Z-Wave.Me
//  All rights reserved
//  info@z-wave.me
//
//  This source file is subject to the terms and conditions of the
//  Z-Wave.Me Software License Agreement which restricts the manner
//  in which it may be used.
//

#ifndef zserialize_download_private_h
#define zserialize_download_private_h

#include "ZPlatform.h"
#include "ZLog.h"
#include "ZStreamPrivate.h"

typedef enum _ZSerializeDownloadHdrField_e
{
    _ZSerializeDownloadHdrFieldContentLength,
    _ZSerializeDownloadHdrFieldContentType
} _ZSerializeDownloadHdrField_t;

typedef enum _ZSerializeDownloadCtxParserState_e
{
    _ZSerializeDownloadCtxParserStateIdle,
    _ZSerializeDownloadCtxParserStateNameFind,
    _ZSerializeDownloadCtxParserStateNameRead,
    _ZSerializeDownloadCtxParserStateNameCmp,
    _ZSerializeDownloadCtxParserStateNameTargetId,
    _ZSerializeDownloadCtxParserStateNameTargetIdExtract,
    _ZSerializeDownloadCtxParserStateNameUrl,
    _ZSerializeDownloadCtxParserStateNameUrlExtract,
    _ZSerializeDownloadCtxParserStateNameFileOpen,
    _ZSerializeDownloadCtxParserStateNameFileWrite,
    _ZSerializeDownloadCtxParserStateNameFileType,
    _ZSerializeDownloadCtxParserStateValueTargetLineBreak1,
    _ZSerializeDownloadCtxParserStateValueTargetLineBreak2,
    _ZSerializeDownloadCtxParserStateErrorRepeatArgument,
} _ZSerializeDownloadCtxParserState_t;

typedef struct _ZSerializeDownloadCtxDataParser_s
{
    ZWCSTR data;
    size_t index;
    size_t length;
} _ZSerializeDownloadCtxDataParser_t;

#define ZSERIALIZE_DOWNLOAD_BOUNDARY_MAX_LENGHT 70

typedef size_t (*_zserialize_download_request_header_handler_t)(void *const args, const ZWSTR dst, const size_t dst_size, const _ZSerializeDownloadHdrField_t field);

typedef struct _ZSerializeDownloadCtx_s
{
    void *args;
    _zserialize_download_request_header_handler_t request_header_handler;
    const _ZStreamRW_t *stream;
    void *ctx_stream;
    size_t content_index;
    size_t content_length;
    size_t boundary_length;
    size_t buffer_common_length;
    ZWCHAR boundary[2 + 2 + ZSERIALIZE_DOWNLOAD_BOUNDARY_MAX_LENGHT]; // CRLF + '--' + max 70 byte
    ZWSTR buffer_common;
    ZWCHAR buffer_tmp[16];
    _ZSerializeDownloadCtxParserState_t state;
    _ZSerializeDownloadCtxParserState_t state_target;
    _ZSerializeDownloadCtxDataParser_t buffer;
    _ZSerializeDownloadCtxDataParser_t buffer_save;
    _ZSerializeDownloadCtxDataParser_t data;
    _ZSerializeDownloadCtxDataParser_t data_save;
    size_t save_find_length;
    ZWSTR url;
    ssize_t targetId;
    ZWBOOL is_file;
} _ZSerializeDownloadCtx_t;

ZWEXPORT_PRIVATE void _zserialize_download_deinit(_ZSerializeDownloadCtx_t *const ctx);
ZWEXPORT_PRIVATE ZWError _zserialize_download_init(_ZSerializeDownloadCtx_t *const ctx, void *const args, const _zserialize_download_request_header_handler_t request_header_handler, const _ZStreamRW_t *const stream, void *const ctx_stream);
ZWEXPORT_PRIVATE ZWError _zserialize_download_parser(_ZSerializeDownloadCtx_t *const ctx, const ZWCSTR data, const size_t length);
ZWEXPORT_PRIVATE ZWSTR _zserialize_download_extract_url(_ZSerializeDownloadCtx_t *const ctx);
static inline ZWBOOL _zserialize_download_is_file(_ZSerializeDownloadCtx_t *const ctx)
{
    return ctx->is_file;
}
static inline ssize_t _zserialize_download_extract_target_id(_ZSerializeDownloadCtx_t *const ctx)
{
    return ctx->targetId;
};

#endif // zserialize_download_private_h